home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <proto/dos.h>
- #include <libraries/dos.h>
-
- #include "os.h"
- #include "capi-usr.h"
-
- #include "MyCAPI.h"
-
-
- /*
- ** einige in ETSI definierte Konstanten
- */
- #define D_ALERTING 0x01
- #define D_CALL_PROCEEDING 0x02
- #define D_SETUP_ACKNOWLEDGE 0x0D
- #define I_Cause 0x08
- #define I_ChannelIdentification 0x18
- #define I_Facility 0x1C
- #define I_DateTime 0x29
-
-
- /*
- ** ist das richtig ???
- */
- #define I_Charging 0x4001
-
-
- /*
- ** Text-Highlighting
- */
- #define HI_ON "\x1b[32m"
- #define HI_OFF "\x1b[31m"
- #define NAMELEN 50
- #define MAXLINELEN 512
-
- /*
- ** Externals
- */
- extern BOOL debugcapi;
- extern U8 *actioncmd;
- extern U8 *phonebook;
- extern U8 outputbuff[];
- extern struct Task *maintask;
- extern VOID myoutput(U8 *, ...);
- extern FILE *phonebookfile;
-
-
- /*
- ** Locals
- */
- static U16 ApplID;
- static U8 manufacturer[64];
- static U32 version[4];
- static U8 serialnumber[8];
-
-
- /*
- ** Code
- */
-
- /****************************************************************************
- ** Ausgaben aus dem CAPI-Callback heraus sollten wir tunlichst
- ** vermeiden (Device-Context !). Daher der Weg ueber eine globale
- ** Variable und ein Signal.
- */
- static VOID out(BOOL flag, U8 *fmt, ...)
- {
- va_list arg;
-
- if (flag) {
- va_start(arg, fmt);
- vsprintf(outputbuff, fmt, arg);
- va_end(arg);
- Signal( maintask, SIGF_SINGLE );
- }
- }
-
-
- /****************************************************************************
- ** Aus einem Array von CAPI-`struct's einen Zeiger auf die <num>te
- ** struct (d.h. auf das Laengenbyte) zurueckgeben
- */
-
- static U8 *GetStruct( U8 *ptr, int num )
- {
- while (num > 0) {
- if (*ptr == 0xFF)
- ptr += (GET_U16(ptr+1) + 3);
- else
- ptr += *ptr + 1;
- num--;
- }
- return ptr;
- }
-
-
- /****************************************************************************
- ** Eine CAPI-Message an den CAPI Treiber schicken
- */
- static U32 SendCAPIMessage( U16 applID, CAPI_MESSAGE *msg, U8 *end )
- {
- msg->TotalLength = end - (U8 *)msg;
- return (U32)U_CAPI_PUT_MESSAGE( applID, msg );
- }
-
-
- /*****************************************************************************
- ** Ermittelt eine evtl. uebertragene CallingNumber
- */
- static VOID GetCallingPartyName(U8 *name, U8 *number)
- {
- U8 rline[MAXLINELEN];
- U8 number1[NAMELEN+2];
- U8 number2[NAMELEN+4];
- U8 index;
- U8 index2;
- U8 anfang;
- U8 ende;
-
- BOOL status;
-
- if(number[0]=='\0')
- {
- name[0]='\0';
- return;
- }
-
- number1[0]='P';
- number1[1]='=';
- number1[2]='\0';
-
- number2[0]='P';
- number2[1]='=';
- number2[2]='"';
- number2[3]='\0';
-
- strcat(number1,number);
- strcat(number2,number);
-
- strcat(number2,"\"");
-
- name[0]='\0';
-
- if (phonebook != NULL)
- {
- if (phonebookfile = fopen(phonebook,"r"))
- {
- while ((fgets(rline, MAXLINELEN, phonebookfile) != NULL) && (name[0] == '\0'))
- {
- if ((strstr(rline,number1) != NULL) || (strstr(rline,number2) != NULL))
- {
- status=FALSE;
- anfang=0;
- ende=0;
- for(index=0;index<=strlen(rline);index++)
- {
- switch(rline[index])
- {
- case '"' :
- status = (status==TRUE) ? FALSE : TRUE;
- break;
- case '=' :
- if ((rline[index-1] == 'N') && (status==FALSE))
- {
- index++;
- anfang = (rline[index] == '"') ? index+1 : index;
- while(!((rline[index] == ' ') && (status == FALSE)) && !((rline[index] == '"') && (status == TRUE)) && !(rline[index] == '\0'))
- {
- if(rline[index]=='"')
- {
- status = (status==TRUE) ? FALSE : TRUE;
- }
- index++;
- }
- ende = (rline[index-1]=='"') ? index-1 : index;
- ende = ((ende-anfang)>=(NAMELEN-1)) ? (anfang+NAMELEN-1) : ende;
- for(index2=anfang;index2<ende;index2++)
- {
- name[index2-anfang]=rline[index2];
- }
- name[index2-anfang]='\0';
- }
- break;
- }
- }
- }
- }
- fclose(phonebookfile);
- }
- }
- return;
- }
-
-
- /*****************************************************************************
- ** Ermittelt eine evtl. uebertragene CallingNumber
- */
- static VOID GetCallingPartyNumber(U8 *p, U8 *callingparty)
- {
- U8 len, type, plan, presentation;
-
- if ((len = callingparty[0]) > 1) {
-
- /*
- ** Number Type ermitteln
- */
- type = (callingparty[1] & 0x70) >> 4;
-
- /*
- ** Numbering plan ermitteln
- */
- plan = (callingparty[1] & 0x0F);
-
- /*
- ** Presentation and Screening Indicator ermitteln
- */
- presentation = callingparty[2] & 0x7F;
-
- switch (type) {
- case 0x00: /* unknown type */
- break;
- case 0x01: /* international number */
- break;
- case 0x02: /* national number */
- *p++ = '0';
- break;
- case 0x03: /* network specific number */
- break;
- case 0x04: /* subsciber number */
- break;
- case 0x06: /* abbreviated number */
- break;
- default: /* reserved */
- break;
- }
- strncpy(p, &callingparty[3], len-2);
- *(p + len - 2) = '\0';
- } else
- strcpy(p, "<Analog>");
- }
-
-
- /*****************************************************************************
- ** Ermittelt eine evtl. uebertragene CalledNumber
- */
- static VOID GetCalledPartyNumber(U8 *p, U8 *calledparty)
- {
- strncpy(p, &calledparty[2], calledparty[0]-1);
- p[calledparty[0]-1] = '\0';
- }
-
-
- /*****************************************************************************
- ** Unser (zugegeben einfacher) CAPI-Signalhandler
- ** (komplexere Applikationen muessen natuerlich auch andere Messages
- ** auswerten und darauf antworten; wir haben es hier einfacher, da
- ** nur LISTEN_CONF, CONNECT_IND, DISCONNECT_IND und INFO_IND kommen
- ** koennen)
- ** data ist der bei U_CAPI_SET_SIGNAL uebergebene Parameter (bei
- ** uns hier NULL)
- */
- static VOID __saveds SignalHandler( U16 applIDdummy, U32 data )
- {
-
- CAPI_MESSAGE *rmsg;
- U32 error;
- BPTR nullfh1, nullfh2;
- nullfh1 = nullfh2 = NULL;
-
- for (;;) {
- U8 *para;
-
- /*
- ** CAPI-Messages vom Treiber abholen und bearbeiten
- */
- error = U_CAPI_GET_MESSAGE( ApplID, &rmsg );
- if (error == 0) {
- if (rmsg) {
-
- /*
- ** Auf Parameterblock setzen
- */
- para = INIT_PARA( rmsg );
- switch (rmsg->Subcommand) {
-
- case CAPISUBCMD_CONF:
- switch (rmsg->Command) {
-
- case CAPICMD_LISTEN:
- out(debugcapi, "LISTEN_CONF");
- break;
-
- default:
- out(debugcapi, "Unknown CONF <0x%04x>", rmsg->Command);
- break;
- }
- break;
-
- case CAPISUBCMD_IND:
- switch (rmsg->Command) {
-
- case CAPICMD_CONNECT:
- {
- U32 plci;
- U16 cip;
- U16 resp = CAPI_REJECT_IGNORE;
- U8 *calledparty;
- U8 *callingparty;
- U8 number[CAPI_MAX_NUMBER_SIZE];
- U8 cnumber[CAPI_MAX_NUMBER_SIZE];
- U8 name[NAMELEN];
-
- GET_PARA( para, U32, plci );
- GET_PARA( para, U16, cip );
- out(debugcapi, "CONNECT_IND 0x%08lx 0x%04x", plci, cip);
- calledparty = GetStruct( para, 0 );
- callingparty = GetStruct( para, 1 );
- GetCallingPartyNumber(number, callingparty);
- GetCalledPartyNumber(cnumber, calledparty);
- GetCallingPartyName(name, number);
-
- out(TRUE, "%s %s %s", cnumber, number, name);
- if (actioncmd != NULL)
- {
- U8 cnta;
- U8 tmp;
- U8 cntc=0;
- U8 cmd[MAXLINELEN];
-
- for(cnta=0;cnta<strlen(actioncmd);cnta++)
- {
- if((actioncmd[cnta]=='%') && (cnta<(strlen(actioncmd)-1)))
- {
- switch(actioncmd[cnta+1])
- {
- case 's':
- cmd[cntc]='\0';
- tmp=48+(cip/10000)%10;
- strcat(cmd,&tmp);
- tmp=48+(cip/ 1000)%10;
- strcat(cmd,&tmp);
- tmp=48+(cip/ 100)%10;
- strcat(cmd,&tmp);
- tmp=48+(cip/ 10)%10;
- strcat(cmd,&tmp);
- tmp=48+(cip/ 1)%10;
- strcat(cmd,&tmp);
- cntc=cntc+5;
- break;
- case 'c':
- cmd[cntc]='\0';
- strcat(cmd,number);
- cntc=cntc+strlen(number);
- break;
- case 'm':
- cmd[cntc]='\0';
- strcat(cmd,cnumber);
- cntc=cntc+strlen(cnumber);
- break;
- case 'n':
- cmd[cntc]='\0';
- strcat(cmd,name);
- cntc=cntc+strlen(name);
- break;
- default:
- cmd[cntc]='%';
- cntc++;
- cmd[cntc]=actioncmd[cnta+1];
- cntc++;
- break;
- }
- cnta++;
- }
- else
- {
- cmd[cntc]=actioncmd[cnta];
- cntc++;
- }
- }
- cmd[cntc]='\0';
- (void)Execute(cmd,nullfh1,nullfh2);
- }
-
- /*
- ** Antwort-Message zusammenfuegen
- */
- para = INIT_PARA( rmsg ) + 4; /* PLCI uebernehmen */
- ADD_PARA( para, U16, resp );
- ADD_PARA( para, U8, 0 ); /* Struct BProtocol */
- ADD_PARA( para, U8, 0 ); /* Struct ConnectedNumber */
- ADD_PARA( para, U8, 0 ); /* Struct ConnectedSubaddress */
- ADD_PARA( para, U8, 0 ); /* Struct LLC */
- ADD_PARA( para, U8, 0 ); /* Struct AdditionalInfo */
- rmsg->Subcommand = CAPISUBCMD_RESP;
- out(debugcapi, "CONNECT_RESP(0x%04x) --> 0x%04lx", resp, error);
- error = SendCAPIMessage( ApplID, rmsg, para );
- }
- break;
-
- case CAPICMD_DISCONNECT:
- {
- U32 plci;
- U16 reason;
-
- GET_PARA( para, U32, plci );
- GET_PARA( para, U16, reason );
- out(debugcapi, "DISCONNECT_IND");
-
- /*
- ** Antwort-Message zusammenfuegen
- */
- para = INIT_PARA( rmsg ) + 4; /* PLCI uebernehmen */
- rmsg->Subcommand = CAPISUBCMD_RESP;
- out(debugcapi, "DISCONNECT_RESP --> 0x%04lx", error);
- error = SendCAPIMessage( ApplID, rmsg, para );
- }
- break;
-
- case CAPICMD_INFO:
- {
- U32 plci;
- U16 infonumber;
- U8 infosize;
-
- GET_PARA( para, U32, plci );
- GET_PARA( para, U16, infonumber );
- GET_PARA( para, U8, infosize ); /* Grösse der Info-Struct */
- if (infonumber & 0x8000) { /* Bits 7..0 sind Message-Type */
- switch (infonumber & 0xFF) {
- case D_ALERTING:
- out(debugcapi, "INFO_IND D_Alerting");
- break;
- case D_CALL_PROCEEDING:
- out(debugcapi, "INFO_IND D_CallProceeding");
- break;
- case D_SETUP_ACKNOWLEDGE:
- out(debugcapi, "INFO_IND D_SetupAcknowledge");
- break;
- default:
- out(debugcapi, "INFO_IND UNKNOWN MESSAGE");
- break;
- }
- } else { /* Bits 7..0 sind Info-Element-Type */
- if (infonumber == I_Charging) {
- U32 cost;
-
- GET_PARA( para, U32, cost);
- out(debugcapi, "INFO_IND I_Charging %ld", cost);
- } else {
- switch (infonumber & 0xFF) {
- case I_ChannelIdentification:
- {
- U8 channelinfo;
-
- GET_PARA( para, U8, channelinfo );
- out(debugcapi, "INFO_IND I_ChannelIdentification 0x%02x", channelinfo);
- }
- break;
-
- case I_Cause:
- {
- U8 cause;
-
- GET_PARA( para, U8, cause );
- out(debugcapi, "INFO_IND I_Cause 0x%02x", cause);
- }
- break;
-
- case I_DateTime:
- {
- U8 year, month, day;
- U8 hour, minute;
-
- GET_PARA( para, U8, year );
- GET_PARA( para, U8, month );
- GET_PARA( para, U8, day );
- GET_PARA( para, U8, hour );
- GET_PARA( para, U8, minute );
- out(debugcapi, "INFO_IND I_DateTime %02d.%02d.%4d %02d:%02d", day, month, year, hour, minute);
- }
- break;
-
- case I_Facility:
- out(debugcapi, "INFO_IND I_Facility");
- break;
-
- default:
- out(debugcapi, "INFO_IND Unknown INFOELEMENT");
- break;
- }
- }
- }
-
- /*
- ** Antwort-Message zusammenfuegen
- */
- para = INIT_PARA( rmsg ) + 4; /* INFO_RESP: Nur PLCI */
- rmsg->Subcommand = CAPISUBCMD_RESP;
- out(debugcapi, "INFO_RESP : 0x%04lx", error);
- error = SendCAPIMessage( ApplID, rmsg, para );
- }
- break;
-
- default:
- out(debugcapi, "Unknown IND <0x%04x>", rmsg->Command);
- break;
- }
- break;
-
- default:
- out(debugcapi, "Unknown SUBCMD <0x%04x>", rmsg->Subcommand);
- break;
- }
- } else {
- out(debugcapi, "Empty Message !!!");
- break;
- }
- } else {
- if (error != CAPI_11_MESSAGE_QUEUE_EMPTY)
- out(debugcapi, "U_CAPI_GET_MESSAGE --> %04lx", error);
- break;
- }
- }
- }
-
-
- /*****************************************************************************
- ** CAPI initialisieren
- */
- BOOL MYCAPI_Init(U32 ctrlnum)
- {
- CAPI_PROFILE profile;
- U32 error;
- U32 infomask = 0x0000007F; /* alles was definiert ist */
- U32 cipmask = 0xFFFFFFFF; /* alle Anruftypen anzeigen
- /*(1L<<CAPI_CIP_SPEECH) | (1L<<CAPI_CIP_AUDIO31);*/
-
- BOOL ret = FALSE;
- /*U8 number[CAPI_MAX_NUMBER_SIZE];
- U8 name[NAMELEN]; */
-
- /*
- ** Erst mal schauen, ob ctrlnum innerhalb des legalen Bereichs liegt,
- ** und mindestens ein Controller vorhanden ist.
- */
-
- /*number[0]='0';
- number[1]='1';
- number[2]='9';
- number[3]='9';
- number[4]='4';
- number[5]='1';
- number[6]='8';
- number[7]='3';
- number[8]='1';
- number[9]='\0';
-
- GetCallingPartyName(name, number);
- myoutput("%s",name);*/
- error = (U32)U_CAPI_GET_PROFILE( &profile, 0 );
- if (!error) {
- if ((profile.NumControllers != 0) && (ctrlnum > 0) && (ctrlnum <= profile.NumControllers)) {
-
- /*
- ** beim CAPI als Applikation registrieren
- */
- error = (U32)U_CAPI_REGISTER( CAPICONNECTIONS, CAPIBUFFERS, CAPIBLOCKSIZE, &ApplID);
- if (!error) {
- struct {
- CAPI_MESSAGE Msg;
- U8 Para[32];
- } listen_req;
- U8 *para = listen_req.Para;
-
- /*
- ** CAPI-Signalhandler einbinden
- */
- error = (U32)U_CAPI_SET_SIGNAL( ApplID, (U32)SignalHandler, (U32)NULL );
- if (!error) {
-
- U_CAPI_GET_MANUFACTURER( manufacturer );
- U_CAPI_GET_VERSION( version );
- U_CAPI_GET_SERIAL_NUMBER( serialnumber );
-
- /* myoutput("Display CallerID (C) 1996 by ith GmbH");
- myoutput("%s", manufacturer); */
-
- if (debugcapi)
- myoutput("started logging (ApplID:0x%04x)", ApplID);
-
- /*
- ** LISTEN_REQ fuer den entsprechenden Controller abschicken.
- */
- listen_req.Msg.Command = CAPICMD_LISTEN;
- listen_req.Msg.Subcommand = CAPISUBCMD_REQ;
- ADD_PARA( para, U32, ctrlnum ); /* Controller */
- ADD_PARA( para, U32, infomask ); /* Info mask */
- ADD_PARA( para, U32, cipmask ); /* CIP mask */
- ADD_PARA( para, U32, 0 ); /* CIP mask 2: reserviert */
- *para++ = 0; /* Calling party number */
- *para++ = 0; /* Calling party subaddress */
- if (debugcapi)
- myoutput("LISTEN_REQ(0x%08lx, 0x%08lx, 0x%08lx) --> 0x%04lx", ctrlnum, infomask, cipmask, error);
- error = SendCAPIMessage( ApplID, &listen_req.Msg, para );
- ret = TRUE;
-
- } else
- if (debugcapi)
- myoutput("U_CAPI_SET_SIGNAL() --> 0x%04lx", error);
- } else
- if (debugcapi)
- myoutput("U_CAPI_REGISTER() --> 0x%04lx", error);
- } else
- if (debugcapi)
- myoutput("Controllernummer nicht im gültigen Bereich.");
- } else
- if (debugcapi)
- myoutput("U_CAPI_GET_PROFILE --> 0x%04lx", error);
-
- return ret;
- }
-
-
- /*****************************************************************************
- ** CAPI-Resourcen freigeben
- */
- VOID MYCAPI_Exit(VOID)
- {
- U32 error;
-
- error = (U32)U_CAPI_RELEASE( ApplID );
- if (debugcapi)
- myoutput("U_CAPI_RELEASE --> 0x%04lx", error);
- }
-